﻿using System;
using System.Collections.Generic;

namespace WgpgCore
{
    public static class ArmoredMessage
    {
        private const String BeginPgpPublicKey = "-----BEGIN PGP PUBLIC KEY BLOCK-----";
        private const String EndPgpPublicKey = "-----END PGP PUBLIC KEY BLOCK-----";
        private const String BeginPgpMessage = "-----BEGIN PGP MESSAGE-----";
        private const String EndPgpMessage = "-----END PGP MESSAGE-----";
        private const String BeginPgpSignedMessage = "-----BEGIN PGP SIGNED MESSAGE-----";
        private const String BeginPgpSignature = "-----BEGIN PGP SIGNATURE-----";
        private const String EndPgpSignature = "-----END PGP SIGNATURE-----";

        public static Boolean HasPgpMessage(String content)
        {
            return ArmoredMessage.InternalHasItem(content, ArmoredMessage.BeginPgpMessage, ArmoredMessage.EndPgpMessage);
        }

        public static Boolean HasPublicKey(String content)
        {
            return ArmoredMessage.InternalHasItem(content, ArmoredMessage.BeginPgpPublicKey, ArmoredMessage.EndPgpPublicKey);
        }

        public static Boolean HasSignature(String content)
        {
            return ArmoredMessage.InternalHasItem(content, ArmoredMessage.BeginPgpSignedMessage, ArmoredMessage.EndPgpSignature);
        }

        public static List<String> ExtractPublicKeys(String content)
        {
            return ArmoredMessage.InternalExtract(content, ArmoredMessage.BeginPgpPublicKey, ArmoredMessage.EndPgpPublicKey);
        }

        public static List<String> ExtractPgpMessages(String content)
        {
            return ArmoredMessage.InternalExtract(content, ArmoredMessage.BeginPgpMessage, ArmoredMessage.EndPgpMessage);
        }

        public static List<String> ExtractSignedMessages(String content)
        {
            return ArmoredMessage.InternalExtract(content, ArmoredMessage.BeginPgpSignedMessage, ArmoredMessage.EndPgpSignature);
        }

        //-----------------------------------------------------------------------------------------

        private static Boolean InternalHasItem(String content, String begin, String end)
        {
            if (String.IsNullOrEmpty(content))
                return false;

            Int32 startIndex = content.IndexOf(begin, StringComparison.Ordinal);
            if (startIndex == -1)
                return false;

            Int32 endIndex = content.IndexOf(end, startIndex, StringComparison.Ordinal);
            return endIndex != -1;
        }

        private static List<String> InternalExtract(String content, String begin, String end)
        {
            if (String.IsNullOrEmpty(content))
                return null;

            List<String> list = null;

            Int32 startIndex = 0;
            Int32 endIndex = 0;

            while (true)
            {
                startIndex = content.IndexOf(begin, startIndex, StringComparison.Ordinal);
                if (startIndex == -1)
                    break;

                endIndex = content.IndexOf(end, startIndex + begin.Length, StringComparison.Ordinal);
                if (endIndex == -1)
                    break;

                if (list == null)
                    list = new List<String>();

                String c = "" + (Char)160;
                String item = content.Substring(startIndex, (endIndex - startIndex) + end.Length);
                item = item.Replace("\r\n\r\n", "\r\n");
                item = item.Replace(c, "");
                item += "\r\n\r\n";
                list.Add(item);

                startIndex = endIndex + end.Length;
            }

            return list;
        }
    }
}
